import Cookies from 'js-cookie';
import { jwtDecode } from 'jwt-decode';
import { useCallback, useEffect } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { useLocation } from 'react-router-dom';

import PageError from '@/pages/sys/error/PageError';
import { useUserToken, useUserInfo, useUserActions } from '@/store/userStore';

import { useRouter } from '../hooks';

const { VITE_LOGOUT_PAGE: LOGINPAGE } = import.meta.env;
const { VITE_AUTH_FLAG: AUTHFLAG } = import.meta.env;
const { VITE_TOKEN: VITETOKEN } = import.meta.env;
const authFlag = AUTHFLAG === 'true';

type Props = {
  children: React.ReactNode;
};
export default function AuthGuard({ children }: Props) {
  const { accessToken } = useUserToken();
  const { username, role: userRole } = useUserInfo();

  const { replace } = useRouter();
  const { setUserToken, setUserInfo } = useUserActions();
  const userInfo = useUserInfo();
  const location = useLocation();

  const check = useCallback(async () => {
    console.log('AuthGuard', location.pathname);
    const publicPaths = ['/login', '/auth', '/register'];
    if (publicPaths.some((path) => location.pathname.startsWith(path))) {
      return;
    }
    const isRuiLogin = true;

    if (!accessToken || !username || !userRole?.code || Cookies.get(VITETOKEN) !== accessToken) {
      const token = Cookies.get(VITETOKEN);
      if (!token) {
        if ((authFlag || !isRuiLogin) && LOGINPAGE) {
          window.location.href = LOGINPAGE;
        } else {
          replace('/login');
          return;
        }
      }

      try {
        const decodedToken = jwtDecode(token);
        const mergeUser = {
          ...userInfo,
          ...decodedToken,
        };
        // 确保_id字段存在，避免类型错误
        if (mergeUser._id) {
          setUserInfo(mergeUser as any);
          setUserToken({ accessToken: token, refreshToken: token });
        }
      } catch (err) {
        console.error(err);
      }
    }
  }, [
    accessToken,
    location.pathname,
    replace,
    setUserInfo,
    setUserToken,
    userInfo,
    userRole?.code,
    username,
  ]);

  useEffect(() => {
    check();
  }, [check]);

  return <ErrorBoundary FallbackComponent={PageError}>{children}</ErrorBoundary>;
}
